/**
 * Copyright (c) 2006 Amgad S Youssef
 * All Rights Reserved.
 * Licensed under the Eclipse Public License - v 1.0
 * For more information see http://www.eclipse.org/legal/epl-v10.html
 */
package org.eclipsejcde.jcbp.builder.checkers;

import java.util.ArrayList;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipsejcde.core.CheckerStatus;
import org.eclipsejcde.core.IChecker;
import org.eclipsejcde.core.ICheckerStatus;
import org.eclipsejcde.core.JCDECore;
import org.eclipsejcde.jcbp.JCBPCore;

/**
 * @author Amgad S Youssef
 * 
 */
public class SIProxyChecker implements IChecker {

	@Override
	public ICheckerStatus[] check(IResource resource) throws CoreException {
		if (!(resource instanceof IFile)) {
			return new ICheckerStatus[] {};
		}
		if (!resource.getName().endsWith(".java")) {
			return new ICheckerStatus[] {};
		}
		IJavaElement javaElement = JavaCore.create(resource);
		if (!(javaElement instanceof ICompilationUnit)) {
			return new ICheckerStatus[] {};
		}
		ICompilationUnit compilationUnit = (ICompilationUnit) javaElement;
		if (JCBPCore.isSOSFrameworkComponent(compilationUnit)) {
			return new ICheckerStatus[] {};
		}
		if (!JCDECore.isShareableClass(compilationUnit)) {
			return new ICheckerStatus[] {};
		}
		
		if (!JCBPCore.isSIProxy(compilationUnit)) {
			return new ICheckerStatus[] { new CheckerStatus(IMarker.SEVERITY_WARNING, "It is recommended to use SIProxy as the super class of all Shareable interface implementers") };
		}

		ArrayList statusList = new ArrayList();
		IType type = compilationUnit.findPrimaryType();
		IMethod[] methods = type.getMethods();
		for (int i = 0; i < methods.length; i++) {
			if (!methods[i].isConstructor()) {
				if (Flags.isPublic(methods[i].getFlags()) && !Flags.isAbstract(methods[i].getFlags())) {
					String methodSource = methods[i].getSource();
					if (removeComments(methodSource).indexOf("isAuthorized()") < 0) {
						ICheckerStatus checkerStatus = new CheckerStatus(IMarker.SEVERITY_WARNING, "It is recommended to use isAuthorized() method in all public methods of a SIProxy class",
								methods[i].getNameRange().getOffset(), methods[i].getNameRange().getOffset() + methods[i].getNameRange().getLength());
						statusList.add(checkerStatus);
					}
				}
			}
		}
		ICheckerStatus[] checkStatuses = new ICheckerStatus[statusList.size()];
		statusList.toArray(checkStatuses);
		return checkStatuses;
	}

	private static String removeComments(String sourceCode) {
		StringBuffer sb = new StringBuffer(sourceCode);
		while (sb.indexOf("/*") > -1 && sb.indexOf("*/", sb.indexOf("/*")) > -1) {
			sb.replace(sb.indexOf("/*"), sb.indexOf("*/", sb.indexOf("/*")) + 2, "");
		}
		while (sb.indexOf("//") > -1 && sb.indexOf("\n", sb.indexOf("//")) > -1) {
			sb.replace(sb.indexOf("//"), sb.indexOf("\n", sb.indexOf("//")) + 1, "");
		}
		return sb.toString();
	}

}
